/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package inventurserver;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author streblow
 */
public class Communicator extends Thread {
    
    private final MainFrame m_MainFrameInstance;
    private final Socket m_Socket;
    
    public Communicator(MainFrame instance, Socket socket) {
        m_MainFrameInstance = instance;
        m_Socket = socket;
    }
    
    @Override
    public void run() {
        DataInputStream dataInputStream = null;
        DataOutputStream dataOutputStream = null;
        String datablock;
        String teamID;
        m_MainFrameInstance.m_Threads += 1;
        if (m_MainFrameInstance.m_Threads > 0)
            m_MainFrameInstance.m_StartStopButton.setEnabled(false);
        try {
                dataInputStream = new DataInputStream(m_Socket.getInputStream());
                dataOutputStream = new DataOutputStream(m_Socket.getOutputStream());
                datablock = dataInputStream.readUTF(); //get teamID
                int id = -1;
                try {
                        id = Integer.parseInt(datablock);
                } catch (NumberFormatException ex) {
                        //ignore error, initial id (-1) results in invalid hash
                }
                if (getHash(id) == m_MainFrameInstance.m_Hash) {
                        dataOutputStream.writeUTF("ok - connection established");
                        m_MainFrameInstance.writeLog("connected to " +
                                m_Socket.getInetAddress().toString() +
                                ":" + m_Socket.getPort());
                        teamID = datablock;
                        m_MainFrameInstance.writeLog("retrieving data from " + teamID);
                        while (true) {
                                datablock = dataInputStream.readUTF();
                                if (!datablock.equalsIgnoreCase("")) {
                                        dataOutputStream.writeUTF("ok");
                                        if (m_MainFrameInstance.m_LogData)
                                            m_MainFrameInstance.writeLog("data (" + teamID + ") - " + datablock);
                                        synchronized(m_MainFrameInstance.m_csvFile) {
                                            m_MainFrameInstance.m_csvFile.m_fwFile.write(teamID + ";" + datablock + "\n");
                                        }
                                } else
                                        break;
                        }
                        m_MainFrameInstance.writeLog("accomplished retrieving data from " + teamID);
                } else {
                        dataOutputStream.writeUTF("error - access denied");
                }
        } catch (IOException ex) {
            Logger.getLogger(Communicator.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(Communicator.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
                if (m_Socket != null) {
                        try {
                                m_Socket.close();
                        } catch (IOException ex) {
                            Logger.getLogger(Communicator.class.getName()).log(Level.SEVERE, null, ex);
                        }
                }
                if (dataInputStream!= null) {
                        try {
                                dataInputStream.close();
                        } catch (IOException ex) {
                            Logger.getLogger(Communicator.class.getName()).log(Level.SEVERE, null, ex);
                        }
                }
                if (dataOutputStream!= null) {
                        try {
                                dataOutputStream.close();
                        } catch (IOException ex) {
                            Logger.getLogger(Communicator.class.getName()).log(Level.SEVERE, null, ex);
                        }
                }
                if (m_MainFrameInstance.m_csvFile.m_fwFile != null) {
                        try {
                                m_MainFrameInstance.m_csvFile.m_fwFile.flush();
                        } catch (IOException ex) {
                            Logger.getLogger(Communicator.class.getName()).log(Level.SEVERE, null, ex);
                        }
                }
        }
        m_MainFrameInstance.m_Threads -= 1;
        if (m_MainFrameInstance.m_Threads == 0)
            m_MainFrameInstance.m_StartStopButton.setEnabled(true);
    }

    public int getHash(int i) {
        //negative numbers are used to generate invalid hash (-1)
        if (i < 0) return -1;
        //calculate digit sum
        int z = 0;
        while (i > 9) {
            z = z + (i % 10);
            i = i / 10;
        }
        z = z + i;
        //return digit sum modulo 10
        return z % 10;
    }
}
